package ve.com.wayoyo.wuml_case.DibujoDiagramas;

import ve.com.wayoyo.wuml_case.Painter;
import android.R.color;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Color;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PointF;

public class CompConector {

	//Constantes
	private static final int ORIENTATION_TOP = 1;
    private static final int ORIENTATION_BOTTOM = 2;
    private static final int ORIENTATION_LEFT = 3;
    private static final int ORIENTATION_RIGHT = 4;
    private static final int ORIENTATION_INNER_TOP = 5;
    private static final int ORIENTATION_INNER_BOTTOM = 6;
    private static final int ORIENTATION_INNER_LEFT = 7;
    private static final int ORIENTATION_INNER_RIGHT = 8;
    private static final int TOUCH_HITBOX_SIZE = 15;
    
    //Estados
    public static final int IDLE_STATE = 1;
    public static final int SELECTED_STATE = 2;
    
    //Tipos de Linea
    public static final int NORMAL_TYPE = 0;
    public static final int DASHED_TYPE = 1;
    public static final int FATHER_SIDE_DASHED = 2; //Solo la mitad correspondiente al padre estara punteada.
    public static final int CHILD_SIDE_DASHED = 3; //Solo la mitad correspondiente al hijo estara punteada.
    
	private int _fatherId;
	private int _childId;
    private Point _fatherCenter;
    private Point _childCenter;
    private int _childQuadrant;
    private int _fatherArrowType;
	private int _childArrowType;
	private int _fatherOrientation;
	private int _childOrientation;
	private int _currentState;
	private int _currentLineType;
	private Path[] _linePath;
	private String _fatherCardenalityLeft = "1";
	private String _fatherCardenalityRight = "1";
	private String _childCardenalityLeft = "1";
	private String _childCardenalityRight = "*";
	
	//Puntos para dibujar la linea
	private Point[] _points = new Point[5];

	//Cantidad de puntos
	private int _numberOfPoints;
	 
	//Tipos de Terminaciones de los conectores
	public static class  _arrowType{
		public static final int Asociacion = 0;//dashed
		public static final int Herencia = 1;//generalizacion y realizacion
		public static final int Asociacion_Directa = 2;//dependencia
		public static final int Agregacion = 3;
		public static final int Composicion = 4;
		public static final int PataDeGallo_PK = 5;
		public static final int PataDeGallo = 6;
		public static final int Union_Simple = 7;
		public static final int Flecha_Llena = 8;
	}
	
	//Pinters
	private Paint _normalLinePaint;
	
	public CompConector(int fatherID,int childID){
		super();
		_fatherId = fatherID;
		_childId = childID;
		_fatherArrowType = _arrowType.Herencia;
		
	}

	public int get_currentLineType() {
		return _currentLineType;
	}


	public void set_currentLineType(int _currentLineType) {
		this._currentLineType = _currentLineType;
	}

	public int get_fatherId() {
		return _fatherId;
	}
	
	public void set_fatherId(int _fatherId) {
		this._fatherId = _fatherId;
	}
	public int get_childId() {
		return _childId;
	}
	public void set_childId(int _childId) {
		this._childId = _childId;
	}
	public int get_numberOfPoints() {
		return _numberOfPoints;
	}
	public void set_numberOfPoints(int _numberOfPoints) {
		this._numberOfPoints = _numberOfPoints;
	}
	public int get_fatherArrowType() {
		return _fatherArrowType;
	}
	public void set_fatherArrowType(int _fatherArrowType) {
		this._fatherArrowType = _fatherArrowType;
	}
	public int get_childArrowType() {
		return _childArrowType;
	}
	public void set_childArrowType(int _childArrowType) {
		this._childArrowType = _childArrowType;
	}
	
	public void setPointOfLine(int posX,int posY,int index){
		try{
			_points[index].set(posX, posY);
		}catch (Exception e){
			
		}
	}
	
	public boolean checkOnTouch(Point touchPoint){
		return false;
	}
	
	public void Dibujar(Canvas c,boolean isFcoused,float globalScale,int offSetX,int offSetY) {
		
		//Dibujamos las lineas del conector
		_linePath = getLinePaths(globalScale,offSetX,offSetY);
		switch (_currentLineType) {
		case DASHED_TYPE:
			c.drawPath(_linePath[0], Painter.getInstancia().getLineTypePaint(_currentState, DASHED_TYPE));
			c.drawPath(_linePath[1], Painter.getInstancia().getLineTypePaint(_currentState, DASHED_TYPE));
			break;
			
		case FATHER_SIDE_DASHED:
			c.drawPath(_linePath[0], Painter.getInstancia().getLineTypePaint(_currentState, DASHED_TYPE));
			c.drawPath(_linePath[1], Painter.getInstancia().getLineTypePaint(_currentState, NORMAL_TYPE));
			break;
			
		case CHILD_SIDE_DASHED:
			c.drawPath(_linePath[0], Painter.getInstancia().getLineTypePaint(_currentState, NORMAL_TYPE));
			c.drawPath(_linePath[1], Painter.getInstancia().getLineTypePaint(_currentState, DASHED_TYPE));
			break;	

		default:
			c.drawPath(_linePath[0], Painter.getInstancia().getLineTypePaint(_currentState, NORMAL_TYPE));
			c.drawPath(_linePath[1], Painter.getInstancia().getLineTypePaint(_currentState, NORMAL_TYPE));
			break;
		}
		
		_normalLinePaint = Painter.getInstancia().getLineTypePaint(_currentState, NORMAL_TYPE);
		//Dibujamos la flecha del padre
		switch (_fatherArrowType) {
		/*
		case _arrowType.Asociacion:
			c.drawLine((_points[0].x+offSetX)*globalScale, (_points[0].y+offSetY)*globalScale, (_points[1].x+offSetX)*globalScale, (_points[1].y+offSetY)*globalScale, _normalLinePaint);
			break;
		*/
		case _arrowType.Herencia:	
			dibujarHerencia(c,globalScale,new Point((int)((_points[0].x+offSetX)*globalScale),(int)((_points[0].y+offSetY)*globalScale)),new Point((int)((_points[1].x+offSetX)*globalScale),(int)((_points[1].y+offSetY)*globalScale)),_fatherOrientation);
			break;
			
		case _arrowType.Asociacion_Directa:
			dibujarAsociacionDirecta(c,globalScale,new Point((int)((_points[0].x+offSetX)*globalScale),(int)((_points[0].y+offSetY)*globalScale)),new Point((int)((_points[1].x+offSetX)*globalScale),(int)((_points[1].y+offSetY)*globalScale)),_fatherOrientation);
			break;
			
		case _arrowType.Composicion:
			dibujarComposicion(c,globalScale,new Point((int)((_points[0].x+offSetX)*globalScale),(int)((_points[0].y+offSetY)*globalScale)),new Point((int)((_points[1].x+offSetX)*globalScale),(int)((_points[1].y+offSetY)*globalScale)),_fatherOrientation,true);
			break;
			
		case _arrowType.Agregacion:
			dibujarComposicion(c,globalScale,new Point((int)((_points[0].x+offSetX)*globalScale),(int)((_points[0].y+offSetY)*globalScale)),new Point((int)((_points[1].x+offSetX)*globalScale),(int)((_points[1].y+offSetY)*globalScale)),_fatherOrientation,false);
			break;
			
		default:
			break;
		}
		
		//Dibujamos la flecha del hijo
		switch (_childArrowType) {
		/*
		case _arrowType.Asociacion:
			c.drawLine((_points[_numberOfPoints-1].x+offSetX)*globalScale, (_points[_numberOfPoints-1].y+offSetY)*globalScale, (_points[_numberOfPoints-2].x+offSetX)*globalScale, (_points[_numberOfPoints-2].y+offSetY)*globalScale, _normalLinePaint);
			break;
		*/
		case _arrowType.Herencia:	
			dibujarHerencia(c,globalScale,new Point((int)((_points[_numberOfPoints-1].x+offSetX)*globalScale),(int)((_points[_numberOfPoints-1].y+offSetY)*globalScale)),new Point((int)((_points[_numberOfPoints-2].x+offSetX)*globalScale),(int)((_points[_numberOfPoints-2].y+offSetY)*globalScale)),_childOrientation);
			break;
			
		case _arrowType.Asociacion_Directa:
			dibujarAsociacionDirecta(c,globalScale,new Point((int)((_points[_numberOfPoints-1].x+offSetX)*globalScale),(int)((_points[_numberOfPoints-1].y+offSetY)*globalScale)),new Point((int)((_points[_numberOfPoints-2].x+offSetX)*globalScale),(int)((_points[_numberOfPoints-2].y+offSetY)*globalScale)),_childOrientation);
			break;
			
		case _arrowType.Composicion:
			dibujarComposicion(c,globalScale,new Point((int)((_points[_numberOfPoints-1].x+offSetX)*globalScale),(int)((_points[_numberOfPoints-1].y+offSetY)*globalScale)),new Point((int)((_points[_numberOfPoints-2].x+offSetX)*globalScale),(int)((_points[_numberOfPoints-2].y+offSetY)*globalScale)),_childOrientation,true);
			break;
			
		case _arrowType.Agregacion:
			dibujarComposicion(c,globalScale,new Point((int)((_points[_numberOfPoints-1].x+offSetX)*globalScale),(int)((_points[_numberOfPoints-1].y+offSetY)*globalScale)),new Point((int)((_points[_numberOfPoints-2].x+offSetX)*globalScale),(int)((_points[_numberOfPoints-2].y+offSetY)*globalScale)),_childOrientation,false);
			break;
			
		default:
			break;
		}
		
		if(_fatherArrowType == _arrowType.Agregacion || _fatherArrowType == _arrowType.Composicion || _childArrowType == _arrowType.Agregacion || _childArrowType == _arrowType.Composicion  ){
			//Dibujamos la cardinalidad del padre
			dibujarCardinalidad(c,new Point(_points[0].x+offSetX,_points[0].y+offSetY), _fatherOrientation, _fatherCardenalityLeft, _fatherCardenalityRight, globalScale);
			
			//Dibujamos la cardinalidad del hijo
			dibujarCardinalidad(c,new Point(_points[_numberOfPoints-1].x+offSetX,_points[_numberOfPoints-1].y+offSetY), _childOrientation, _childCardenalityLeft, _childCardenalityRight, globalScale);
		}
	}
	
	private int calcularDistTotal(){
		int respuesta = 0;
		for (int i = 0; i < _numberOfPoints-1; i++) {
			respuesta += Math.hypot(_points[i].x-_points[i+1].x, _points[i].y-_points[i+1].y);
		}
		return respuesta;
	}
	
	private int calcularDistEntrePuntos(Point a, Point b){
		int respuesta =(int)Math.hypot(a.x-b.x, a.y-b.y);
		return respuesta;
	}
	
	private Path[] getLinePaths(float globalScale,int offSetX,int offSetY){
		Path[] respuesta = new Path[2];
		int midPoint = 0;
		int DistanciaMedia = calcularDistTotal()/2;
		int DistAcum = 0;
		int DistActual;
		Point puntoMedio;
		respuesta[0] = new Path();
		respuesta[0].moveTo((_points[0].x+offSetX)*globalScale, (_points[0].y+offSetY)*globalScale);
		for(int i = 0; i < _numberOfPoints-1;i++){
			DistActual = calcularDistEntrePuntos(_points[i],_points[i+1]);
			if(DistActual + DistAcum >= DistanciaMedia ){
				puntoMedio = new Point();
				puntoMedio.set((int)((((_points[i+1].x+_points[i].x)/2)+offSetX)*globalScale),(int)((((_points[i+1].y+_points[i].y)/2)+offSetY)*globalScale));
				respuesta[0].lineTo(puntoMedio.x, puntoMedio.y);
				respuesta[1] = new Path();
				respuesta[1].moveTo(puntoMedio.x, puntoMedio.y);
				midPoint = i+1;
				break;
			}else{
				DistAcum += DistActual;
				respuesta[0].lineTo((_points[i+1].x+offSetX)*globalScale, (_points[i+1].y+offSetY)*globalScale);
			}
		}
		respuesta[1].lineTo((_points[midPoint].x+offSetX)*globalScale, (_points[midPoint].y+offSetY)*globalScale);
		for(int i = midPoint;i < _numberOfPoints-1;i++){
			respuesta[1].lineTo((_points[i+1].x+offSetX)*globalScale, (_points[i+1].y+offSetY)*globalScale);
		}
		return respuesta;
	}
	
	public void dibujarHerencia(Canvas c,float globalScale,Point begin,Point end,int orientation ) {
		Path myPath = new Path();
		switch (orientation){
		
		case ORIENTATION_TOP:
			myPath.moveTo(begin.x+(10*globalScale), begin.y-(20*globalScale));
			myPath.lineTo(begin.x, begin.y);
			myPath.lineTo(begin.x-(10*globalScale), begin.y-(20*globalScale));
			myPath.close();
			c.drawPath(myPath, Painter.getInstancia().getFillPaint());
			c.drawPath(myPath, Painter.getInstancia().getArrowPaint(_currentState, false));
			break;
		case ORIENTATION_BOTTOM:
			myPath.moveTo(begin.x+(10*globalScale), begin.y+(20*globalScale));
			myPath.lineTo(begin.x, begin.y);
			myPath.lineTo(begin.x-(10*globalScale), begin.y+(20*globalScale));
			myPath.close();
			c.drawPath(myPath, Painter.getInstancia().getFillPaint());
			c.drawPath(myPath, Painter.getInstancia().getArrowPaint(_currentState, false));
			break;
			
		case ORIENTATION_LEFT:
			myPath.moveTo(begin.x-(20*globalScale), begin.y-(10*globalScale));
			myPath.lineTo(begin.x, begin.y);
			myPath.lineTo(begin.x-(20*globalScale),begin.y+(10*globalScale));
			myPath.close();
			c.drawPath(myPath, Painter.getInstancia().getFillPaint());
			c.drawPath(myPath, Painter.getInstancia().getArrowPaint(_currentState, false));
			break;
			
		case ORIENTATION_RIGHT:
			myPath.moveTo(begin.x+(20*globalScale), begin.y-(10*globalScale));
			myPath.lineTo(begin.x, begin.y);
			myPath.lineTo(begin.x+(20*globalScale),begin.y+(10*globalScale));
			myPath.close();
			c.drawPath(myPath, Painter.getInstancia().getFillPaint());
			c.drawPath(myPath, Painter.getInstancia().getArrowPaint(_currentState, false));
			break;
			
		default:
			break;
		}
	}
	
	public void dibujarAsociacionDirecta(Canvas c,float globalScale,Point begin,Point end,int orientation ) {
		
		switch (orientation){
		
		case ORIENTATION_TOP:
			c.drawLine(begin.x, begin.y, begin.x+(10*globalScale), begin.y-(20*globalScale), _normalLinePaint);
			c.drawLine(begin.x, begin.y, begin.x-(10*globalScale), begin.y-(20*globalScale), _normalLinePaint);
			break;
		case ORIENTATION_BOTTOM:
			c.drawLine(begin.x, begin.y, begin.x+(10*globalScale), begin.y+(20*globalScale), _normalLinePaint);
			c.drawLine(begin.x, begin.y, begin.x-(10*globalScale), begin.y+(20*globalScale), _normalLinePaint);
			break;
			
		case ORIENTATION_LEFT:
			c.drawLine(begin.x, begin.y, begin.x-(20*globalScale), begin.y+(10*globalScale), _normalLinePaint);
			c.drawLine(begin.x, begin.y, begin.x-(20*globalScale), begin.y-(10*globalScale), _normalLinePaint);
			break;
			
		case ORIENTATION_RIGHT:
			c.drawLine(begin.x, begin.y, begin.x+(20*globalScale), begin.y-(10*globalScale), _normalLinePaint);
			c.drawLine(begin.x, begin.y, begin.x+(20*globalScale), begin.y+(10*globalScale), _normalLinePaint);
			break;
		default:
			
			break;
		}
	}
	
	public void dibujarComposicion(Canvas c,float globalScale,Point begin,Point end,int orientation ,boolean isStrong){
		Path myPath = new Path();
		switch (orientation){
		
		case ORIENTATION_TOP:
			myPath.moveTo(begin.x+(12*globalScale), begin.y-(15*globalScale));
			myPath.lineTo(begin.x, begin.y);
			myPath.lineTo(begin.x-(12*globalScale), begin.y-(15*globalScale));
			myPath.lineTo(begin.x, begin.y-(30*globalScale));
			myPath.close();
			if(isStrong){
				c.drawPath(myPath, Painter.getInstancia().getArrowPaint(_currentState, true));
			}else{
				c.drawPath(myPath, Painter.getInstancia().getFillPaint());
				c.drawPath(myPath, Painter.getInstancia().getArrowPaint(_currentState, false));
			}
			break;
		case ORIENTATION_BOTTOM:
			myPath.moveTo(begin.x+(12*globalScale), begin.y+(15*globalScale));
			myPath.lineTo(begin.x, begin.y);
			myPath.lineTo(begin.x-(12*globalScale), begin.y+(15*globalScale));
			myPath.lineTo(begin.x, begin.y+(30*globalScale));
			myPath.close();
			if(isStrong){
				c.drawPath(myPath, Painter.getInstancia().getArrowPaint(_currentState, true));
			}else{
				c.drawPath(myPath, Painter.getInstancia().getFillPaint());
				c.drawPath(myPath, Painter.getInstancia().getArrowPaint(_currentState, false));
			}
			break;
			
		case ORIENTATION_LEFT:
			myPath.moveTo(begin.x-(15*globalScale), begin.y-(12*globalScale));
			myPath.lineTo(begin.x, begin.y);
			myPath.lineTo(begin.x-(15*globalScale),begin.y+(12*globalScale));
			myPath.lineTo(begin.x-(30*globalScale),begin.y);
			myPath.close();
			if(isStrong){
				c.drawPath(myPath, Painter.getInstancia().getArrowPaint(_currentState, true));
			}else{
				c.drawPath(myPath, Painter.getInstancia().getFillPaint());
				c.drawPath(myPath, Painter.getInstancia().getArrowPaint(_currentState, false));
			}
			break;
			
		case ORIENTATION_RIGHT:
			myPath.moveTo(begin.x+(15*globalScale), begin.y-(12*globalScale));
			myPath.lineTo(begin.x, begin.y);
			myPath.lineTo(begin.x+(15*globalScale),begin.y+(12*globalScale));
			myPath.lineTo(begin.x+(30*globalScale),begin.y);
			myPath.close();
			if(isStrong){
				c.drawPath(myPath, Painter.getInstancia().getArrowPaint(_currentState, true));
			}else{
				c.drawPath(myPath, Painter.getInstancia().getFillPaint());
				c.drawPath(myPath, Painter.getInstancia().getArrowPaint(_currentState, false));
			}
			break;
			
		default:
			break;
		}
		
	}
	public void dibujarCardinalidad(Canvas c,Point anchor,int orientation,String M,String N,float globalScale){
		String Cardinalidad = "";
		Paint textPaint = Painter.getInstancia().getTextPaint(false, globalScale);
		textPaint.setTextSize(15*globalScale);
		try{
			if(N.equals("*")){
				if(Integer.valueOf(M) == 1){
					Cardinalidad = "*";
				}else{
					Cardinalidad = M + ".." + N;
				}
			}else{
				if(Integer.valueOf(M) == Integer.valueOf(N)){
					Cardinalidad = M;
				}else{
					Cardinalidad = M + ".." + N;
				}
			}
		}
		catch (Exception e) {
			System.out.println(e.getMessage());
		}
		switch (orientation) {
		case ORIENTATION_TOP:
			c.drawText(Cardinalidad, (anchor.x+7)*globalScale, (anchor.y-25)*globalScale,textPaint);
			break;
			
		case ORIENTATION_BOTTOM:
			c.drawText(Cardinalidad, (anchor.x+7)*globalScale, (anchor.y+35)*globalScale,textPaint);
			break;
			
		case ORIENTATION_LEFT:
			c.drawText(Cardinalidad, (anchor.x-30-textPaint.measureText(Cardinalidad))*globalScale, (anchor.y-7)*globalScale,textPaint);
			break;
			
		case ORIENTATION_RIGHT:
			c.drawText(Cardinalidad, (anchor.x+30)*globalScale, (anchor.y-7)*globalScale,textPaint);
			break;
			
		default:
			break;
		}
	}
	public void CalcularConexiones(Componente father, Componente child){
		_fatherCenter = father.get_centerPoint();
		_childCenter = child.get_centerPoint();
		
		int Ax = father.Anchor.x;
		int AxWith = (int) (Ax + father.get_width());
		int Ay = father.Anchor.y;
		int AyHeight = (int) (Ay + father.get_width());
		//Ubicar Cuadrante
		
		if(child.get_centerPoint().y <= Ay){ //Cuadrantes Superiores
			if(Ax > child.get_centerPoint().x){// Cuadrante Derecho
				_childQuadrant = 8;
				_numberOfPoints = 3;
				_points[0] = father.get_topAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_TOP;
				_points[2] = child.get_rightAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_RIGHT;
				calcularRutaIntermedia();
			}else if (child.get_centerPoint().x > AxWith){ //Cuadrante Izquierdo
				_childQuadrant = 2;
				_numberOfPoints = 3;
				_points[0] = father.get_topAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_TOP;
				_points[2] = child.get_leftAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_LEFT;
				calcularRutaIntermedia();
			}else{
				_childQuadrant = 1;
				_numberOfPoints = 4;
				_points[0] = father.get_topAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_TOP;
				_points[3] = child.get_bottomAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_BOTTOM;
				calcularRutaIntermedia();
			}
		}else if( child.get_centerPoint().y >= AyHeight){//Cuadrantes Inferiores
			if(Ax > child.get_centerPoint().x){// Cuadrante Derecho
				_childQuadrant = 6;
				_numberOfPoints = 3;
				_points[0] = father.get_bottomAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_BOTTOM;
				_points[2] = child.get_rightAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_RIGHT;
				calcularRutaIntermedia();
			}else if (child.get_centerPoint().x > AxWith){ //Cuadrante Izquierdo
				_childQuadrant = 4;
				_numberOfPoints = 3;
				_points[0] = father.get_bottomAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_BOTTOM;
				_points[2] = child.get_leftAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_LEFT;				
				calcularRutaIntermedia();
			}else{
				_childQuadrant = 5;
				_numberOfPoints = 4;
				_points[0] = father.get_bottomAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_BOTTOM;
				_points[3] = child.get_topAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_TOP;
				calcularRutaIntermedia();
			}
		}else{//Cuadrantes Medios
			if(Ax > child.get_centerPoint().x){// Cuadrante Derecho
				_childQuadrant = 7;
				_numberOfPoints = 4;
				_points[0] = father.get_leftAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_LEFT;
				_points[3] = child.get_rightAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_RIGHT;
				calcularRutaIntermedia();
			}else if (child.get_centerPoint().x > AxWith){ //Cuadrante Izquierdo
				_childQuadrant = 3;
				_numberOfPoints = 4;
				_points[0] = father.get_rightAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_RIGHT;
				_points[3] = child.get_leftAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_LEFT;
				calcularRutaIntermedia();
			}else{
				_childQuadrant = 0;
				_numberOfPoints = 2;
				_points[0] = father.get_leftAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_INNER_LEFT;
				_points[1] = child.get_leftAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_LEFT;
			}
		}

	}
	
	public void actualizarRuta(Componente father){
		
		int Ax = father.Anchor.x;
		int AxWith = (int) (Ax + father.get_width());
		int Ay = father.Anchor.y;
		int AyHeight = (int) (Ay + father.get_width());
		//Ubicar Cuadrante
		
		if(_childCenter.y <= Ay){ //Cuadrantes Superiores
			if(Ax > _childCenter.x){// Cuadrante Derecho
				if(_childQuadrant != 8){
					_childQuadrant = 8;
					_numberOfPoints = 3;
					_points[0] = father.get_topAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_TOP;
					_points[2] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_rightAnchors().obtenerPosicion();
					_childOrientation = ORIENTATION_RIGHT;
				}
				calcularRutaIntermedia();
			}else if (_childCenter.x > AxWith){ //Cuadrante Izquierdo
				if(_childQuadrant != 2){
					_childQuadrant = 2;
					_numberOfPoints = 3;
					_points[0] = father.get_topAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_TOP;
					_points[2] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_leftAnchors().obtenerPosicion();
					_childOrientation = ORIENTATION_LEFT;
				}
				calcularRutaIntermedia();
			}else{
				if(_childQuadrant != 1){
					_childQuadrant = 1;
					_numberOfPoints = 4;
					_points[0] = father.get_topAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_TOP;
					_points[3] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_bottomAnchors().obtenerPosicion();
					_childOrientation = ORIENTATION_BOTTOM;
				}
				calcularRutaIntermedia();
			}
		}else if(_childCenter.y >= AyHeight){//Cuadrantes Inferiores
			if(Ax > _childCenter.x){// Cuadrante Derecho
				if(_childQuadrant != 6){
					_childQuadrant = 6;
					_numberOfPoints = 3;
					_points[0] = father.get_bottomAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_BOTTOM;
					_points[2] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_rightAnchors().obtenerPosicion();
					_childOrientation = ORIENTATION_RIGHT;
				}
				calcularRutaIntermedia();
			}else if (_childCenter.x > AxWith){ //Cuadrante Izquierdo
				if(_childQuadrant != 4){
					_childQuadrant = 4;
					_numberOfPoints = 3;
					_points[0] = father.get_bottomAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_BOTTOM;
					_points[2] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_leftAnchors().obtenerPosicion();
					_childOrientation = ORIENTATION_LEFT;
				}
				calcularRutaIntermedia();
			}else{
				if(_childQuadrant != 5){
					_childQuadrant = 5;
					_numberOfPoints = 4;
					_points[0] = father.get_bottomAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_BOTTOM;
					_points[3] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_topAnchors().obtenerPosicion();
					_childOrientation = ORIENTATION_TOP;
				}
				calcularRutaIntermedia();
			}
		}else{//Cuadrantes Medios
			if(Ax > _childCenter.x){// Cuadrante Derecho
				if(_childQuadrant != 7){
					_childQuadrant = 7;
					_numberOfPoints = 4;
					_points[0] = father.get_leftAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_LEFT;
					_points[3] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_rightAnchors().obtenerPosicion();
					_childOrientation =ORIENTATION_RIGHT;
				}
				calcularRutaIntermedia();
			}else if (_childCenter.x > AxWith){ //Cuadrante Izquierdo
				if(_childQuadrant != 3){
					_childQuadrant = 3;
					_numberOfPoints = 4;
					_points[0] = father.get_rightAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_RIGHT;
					_points[3] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_leftAnchors().obtenerPosicion();
					_childOrientation = ORIENTATION_LEFT;
				}
				calcularRutaIntermedia();
			}else{
				if(_childQuadrant != 0){
					_childQuadrant = 0;
					_numberOfPoints = 2;
					_points[0] = father.get_leftAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_INNER_LEFT;
					_points[1] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_leftAnchors().obtenerPosicion();
					_childOrientation = ORIENTATION_LEFT;
				}
			}
		}
	}
	
	public void calcularRutaIntermedia(){
		switch (_numberOfPoints) {
			case 3:
				_points[1] = new Point(_points[0].x, _points[2].y);
			break;
			case 4:
				if(_childQuadrant == 7 || _childQuadrant == 3){
					int dist = (_points[3].x-_points[0].x)/2;
					_points[1] = new Point((_points[0].x+dist), _points[0].y);
					_points[2] = new Point((_points[0].x+dist), _points[3].y);
				}else{
					int dist = (_points[3].y-_points[0].y)/2;
					_points[1] = new Point(_points[0].x, _points[0].y+dist);
					_points[2] = new Point(_points[3].x, _points[0].y+dist);
				}
			break;
			default:
			break;
		}
	}
	
	public boolean calcularTouch(Point touch){
		boolean respuesta = false;
		Point inter;
		for (int i = 0; i < _numberOfPoints-1; i++) {
			if(calcularDist(_points[i], _points[i+1], touch) <= TOUCH_HITBOX_SIZE){
				inter = calcularPuntoInterseccion(_points[i], _points[i+1], touch);
				respuesta = checkearPuntoEnSegmento(_points[i], _points[i+1], inter);
			}
		}
		return respuesta;		
	}
	
	private float calcularDist(Point lineStart,Point lineEnd,Point punto){
		float respuesta = 0;
		if(lineEnd.x - lineStart.x == 0){ //Si la recta es VERTICAL
			respuesta = Math.abs(lineStart.x - punto.x); //Regresamos la diferencia entre las X
		}else if (lineEnd.y - lineStart.y == 0){//Si la recta es HORIZONTAL
			respuesta = Math.abs(lineStart.y - punto.y); //Regresamos la diferencia entre las Y
		}else{//En caso de que la recta tenga una pendiente distinta de 0 o infinita
			float m = (lineStart.y - punto.y)/(lineEnd.x - lineStart.x);
			float c = (m*lineStart.x-lineStart.y);
			respuesta = (float) (Math.abs((punto.x*-m)+punto.y+c)/Math.hypot(m, 1));
		}
		System.out.println("Calculo de distancia= " + respuesta);
		return respuesta;
	}
	
	private Point calcularPuntoInterseccion(Point lineStart,Point lineEnd,Point punto){
		Point respuesta;
		if(lineEnd.x - lineStart.x == 0){ //Si la recta es VERTICAL
			respuesta = new Point(lineStart.x,punto.y);
		}else if (lineEnd.y - lineStart.y == 0){//Si la recta es HORIZONTAL
			respuesta = new Point(punto.x,lineStart.y);
		}else{
			float m = (lineStart.y - punto.y)/(lineEnd.x - lineStart.x);
			float B1 = (-m*lineStart.x)+lineStart.y;
			float B2 = (punto.x/m)+punto.y;
			float x = (m*(B2-B1))/((m*m)+1);
			float y = (x*m) + B1;
			respuesta = new Point((int)x,(int)y);
		}
		return respuesta;
	}
	
	private boolean checkearPuntoEnSegmento(Point start,Point end,Point test){
		boolean respuesta = false;
		int compX = (start.x - test.x)*(end.x - test.x);
		int compY = (start.y - test.y)*(end.y - test.y);
		if(compX <= 0 && compY <= 0){
			if(compX*compY >= 0)
				respuesta = true;
		}
		return respuesta;
	}
	
	public void setState(int State){
		_currentState = State;
	}
	
	
}
